import { useRef } from 'react';

import { ReactComponent as Chevron } from '@/assets/images/shared/icon-chevron.svg';
import { CourseCard, CourseCardLoader, productApi } from '@/entities/course';
import { transformArrayIntoObject } from '@/shared/lib';
import { Button, Container, Grid, Modal, Select, Title, Wrapper } from '@/shared/ui';
import { Filters, useFilters, useIsInputInFocus, useSorts } from '@/widgets/Filters';
import { Footer } from '@/widgets/Footer';
import { Header } from '@/widgets/Header';
import cn from 'classnames';
import { useRouter } from 'next/router';
import { useDebounceValue } from 'usehooks-ts';

import cs from './Catalog.module.scss';
import { NothingFound } from './ui/NothingFound';
import { SortModal } from './ui/SortModal';

const sorts = [
  { id: 0, title: 'По популярности' },
  { id: 'ASC', title: 'По возрастанию цены' },
  { id: 'DESC', title: 'По уменьшению цены' },
];
export const Catalog = () => {
  const { data: topics } = productApi.useGetTopicsQuery();
  const { data: formats } = productApi.useGetFormatsQuery();
  const router = useRouter();
  const [search] = useDebounceValue((router.query.search as string) || '', 300);

  const inputRef = useRef<HTMLInputElement>(null);

  const { isSortsOpen, selectedSort, handleSelectSort, handleOpenSortModal, handleCloseSortModal } = useSorts({
    sorts,
  });

  const isInputInFocusProps = useIsInputInFocus({ inputRef });
  const filterProps = useFilters();
  const { selectedPool } = filterProps;
  const isInputMode = isInputInFocusProps.isInputInFocus || search;

  const selectedFormats = selectedPool.filter((v) => v.arr === 'formats');
  const selectedTopics = selectedPool.filter((v) => v.arr === 'topics');

  const searchQuery = { search, 'orderBy[order]': 'DESC' as const };
  const filterQuery = {
    'orderBy[order]': selectedSort?.id ? undefined : ('DESC' as const),
    'orderBy[price]': selectedSort.id !== 0 ? (selectedSort.id as 'DESC' | 'ASC') : undefined,
    'filters[formats]': selectedFormats?.length ? selectedFormats.map((v) => v.id).toString() : undefined,
    'filters[topics]': selectedTopics?.length ? selectedTopics.map((v) => v.id).toString() : undefined,
  };
  const query = isInputMode ? searchQuery : filterQuery;

  const { data: courses, isLoading: isFetching } = productApi.useGetProductsQuery({ ...query, limit: 100 });

  return (
    <>
      <Header className={cn(isInputMode && 'hidden_mobile')} />
      <Wrapper>
        <Container>
          <Title className={cn(cs.title, isInputMode && 'hidden_mobile')} tag="h1">
            Учимся
          </Title>
          <Filters
            {...isInputInFocusProps}
            {...filterProps}
            formats={formats?.formats}
            inputRef={inputRef}
            isInputMode={!!isInputMode}
            searchClassName={cs.input_container}
            topics={topics?.topics}
          >
            <>
              <div
                aria-label={`Сортировать ${selectedSort?.title.toLowerCase()}`}
                className={cn(cs.sort_container, isInputMode && 'hidden')}
                data-testid="select-sort"
              >
                <Select
                  className={cs.sort}
                  config={{ title: selectedSort.title, values: sorts }}
                  containerClassName={cn(isInputMode && 'hidden')}
                  isRight
                  isSingle
                  onSelect={handleSelectSort}
                  placeholderClassName={null}
                  selected={sorts.filter((item) => item.id.toString() === selectedSort.id.toString())}
                  width={180}
                  withPlaceholder={selectedSort.title}
                />
              </div>
              <Button
                aria-label={`Сортировать ${selectedSort?.title.toLowerCase()}`}
                className={cn(cs.sort_mobile, isSortsOpen && cs.sort_mobile_no_hover, isInputMode && 'hidden')}
                data-testid="button-open_sort"
                onClick={handleOpenSortModal}
              >
                <span>{selectedSort?.title}</span> <Chevron height={16} width={16} />
              </Button>
            </>
          </Filters>

          {!isFetching && !!courses?.courses?.length && (
            <Grid>
              {courses?.courses.map(({ id, product }, index) => (
                <CourseCard
                  discount={product?.discount}
                  discountPrice={product?.discountPrice}
                  id={id}
                  image={product?.image}
                  isAdvertising={product?.superOrder > 0}
                  key={id}
                  price={product?.price}
                  priority={index < 5}
                  rate={product?.averageRate as unknown as number}
                  title={product?.title}
                />
              ))}
            </Grid>
          )}
          {isFetching && (
            <Grid>
              {transformArrayIntoObject(Array(10).fill(1)).map(({ id }) => (
                <CourseCardLoader key={id} />
              ))}
            </Grid>
          )}
          {courses?.courses?.length === 0 && <NothingFound />}
        </Container>
      </Wrapper>
      <Footer className={cs.footer} />
      <Modal isMobile isOpen={isSortsOpen} onCloseClick={handleCloseSortModal}>
        <SortModal handleSelect={handleSelectSort} sort={selectedSort} sorts={sorts} />
      </Modal>
    </>
  );
};
